home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / ixemul / include / math-68881.h < prev    next >
C/C++ Source or Header  |  1997-10-28  |  10KB  |  559 lines

  1. /******************************************************************\
  2. *                                   *
  3. *  <math-68881.h>        last modified: 18 May 1989.       *
  4. *                                   *
  5. *  Copyright (C) 1989 by Matthew Self.                   *
  6. *  You may freely distribute verbatim copies of this software       *
  7. *  provided that this copyright notice is retained in all copies.  *
  8. *  You may distribute modifications to this software under the     *
  9. *  conditions above if you also clearly note such modifications    *
  10. *  with their author and date.                               *
  11. *                                   *
  12. *  Note:  errno is not set to EDOM when domain errors occur for    *
  13. *  most of these functions.  Rather, it is assumed that the       *
  14. *  68881's OPERR exception will be enabled and handled           *
  15. *  appropriately by the    operating system.  Similarly, overflow       *
  16. *  and underflow do not set errno to ERANGE.               *
  17. *                                   *
  18. *  Send bugs to Matthew Self (self@bayes.arc.nasa.gov).           *
  19. *                                   *
  20. \******************************************************************/
  21.  
  22. /* Dec 1991  - mw - added support for -traditional mode */
  23.  
  24. #include <errno.h>
  25.  
  26. #if defined(__STDC__) || defined(__cplusplus)
  27. #define _DEFUN(name, args1, args2) name ( args2 )
  28. #define _AND ,
  29. #define _CONST const
  30. #else
  31. #define _DEFUN(name, args1, args2) name args1 args2;
  32. #define _AND ;
  33. #define _CONST
  34. #endif
  35.  
  36. #ifndef HUGE_VAL
  37. #define HUGE_VAL                            \
  38. ({                                    \
  39.   double huge_val;                            \
  40.                                     \
  41.   __asm ("fmove%.d #0x7ff0000000000000,%0"    /* Infinity */        \
  42.      : "=f" (huge_val)                        \
  43.      : /* no inputs */);                        \
  44.   huge_val;                                \
  45. })
  46. #endif
  47.  
  48. __inline static _CONST double 
  49. _DEFUN(sin, (x),
  50.     double x)
  51. {
  52.   double value;
  53.  
  54.   __asm ("fsin%.x %1,%0"
  55.      : "=f" (value)
  56.      : "f" (x));
  57.   return value;
  58. }
  59.  
  60. __inline static _CONST double 
  61. _DEFUN(cos, (x),
  62.     double x)
  63. {
  64.   double value;
  65.  
  66.   __asm ("fcos%.x %1,%0"
  67.      : "=f" (value)
  68.      : "f" (x));
  69.   return value;
  70. }
  71.  
  72. __inline static _CONST double 
  73. _DEFUN(tan, (x),
  74.     double x)
  75. {
  76.   double value;
  77.  
  78.   __asm ("ftan%.x %1,%0"
  79.      : "=f" (value)
  80.      : "f" (x));
  81.   return value;
  82. }
  83.  
  84. __inline static _CONST double 
  85. _DEFUN(asin, (x),
  86.     double x)
  87. {
  88.   double value;
  89.  
  90.   __asm ("fasin%.x %1,%0"
  91.      : "=f" (value)
  92.      : "f" (x));
  93.   return value;
  94. }
  95.  
  96. __inline static _CONST double 
  97. _DEFUN(acos, (x),
  98.     double x)
  99. {
  100.   double value;
  101.  
  102.   __asm ("facos%.x %1,%0"
  103.      : "=f" (value)
  104.      : "f" (x));
  105.   return value;
  106. }
  107.  
  108. __inline static _CONST double 
  109. _DEFUN(atan, (x),
  110.     double x)
  111. {
  112.   double value;
  113.  
  114.   __asm ("fatan%.x %1,%0"
  115.      : "=f" (value)
  116.      : "f" (x));
  117.   return value;
  118. }
  119.  
  120. __inline static _CONST double 
  121. _DEFUN(atan2, (y, x),
  122.     double y _AND
  123.     double x)
  124. {
  125.   double pi, pi_over_2;
  126.  
  127.   __asm ("fmovecr%.x %#0,%0"        /* extended precision pi */
  128.      : "=f" (pi)
  129.      : /* no inputs */ );
  130.   __asm ("fscale%.b %#-1,%0"        /* no loss of accuracy */
  131.      : "=f" (pi_over_2)
  132.      : "0" (pi));
  133.   if (x > 0)
  134.     {
  135.       if (y > 0)
  136.     {
  137.       if (x > y)
  138.         return atan (y / x);
  139.       else
  140.         return pi_over_2 - atan (x / y);
  141.     }
  142.       else
  143.     {
  144.       if (x > -y)
  145.         return atan (y / x);
  146.       else
  147.         return - pi_over_2 - atan (x / y);
  148.     }
  149.     }
  150.   else
  151.     {
  152.       if (y > 0)
  153.     {
  154.       if (-x > y)
  155.         return pi + atan (y / x);
  156.       else
  157.         return pi_over_2 - atan (x / y);
  158.     }
  159.       else
  160.     {
  161.       if (-x > -y)
  162.         return - pi + atan (y / x);
  163.       else if (y < 0)
  164.         return - pi_over_2 - atan (x / y);
  165.       else
  166.         {
  167.           double value;
  168. #ifdef _KERNEL
  169.           usetup;
  170. #endif
  171.  
  172.           errno = EDOM;
  173.           __asm ("fmove%.d %#0rnan,%0"     /* quiet NaN */
  174.              : "=f" (value)
  175.              : /* no inputs */);
  176.           return value;
  177.         }
  178.     }
  179.     }
  180. }
  181.  
  182. __inline static _CONST double 
  183. _DEFUN(sinh, (x),
  184.     double x)
  185. {
  186.   double value;
  187.  
  188.   __asm ("fsinh%.x %1,%0"
  189.      : "=f" (value)
  190.      : "f" (x));
  191.   return value;
  192. }
  193.  
  194. __inline static _CONST double 
  195. _DEFUN(cosh, (x),
  196.     double x)
  197. {
  198.   double value;
  199.  
  200.   __asm ("fcosh%.x %1,%0"
  201.      : "=f" (value)
  202.      : "f" (x));
  203.   return value;
  204. }
  205.  
  206. __inline static _CONST double 
  207. _DEFUN(tanh, (x),
  208.     double x)
  209. {
  210.   double value;
  211.  
  212.   __asm ("ftanh%.x %1,%0"
  213.      : "=f" (value)
  214.      : "f" (x));
  215.   return value;
  216. }
  217.  
  218. __inline static _CONST double 
  219. _DEFUN(atanh, (x),
  220.     double x)
  221. {
  222.   double value;
  223.  
  224.   __asm ("fatanh%.x %1,%0"
  225.      : "=f" (value)
  226.      : "f" (x));
  227.   return value;
  228. }
  229.  
  230. __inline static _CONST double 
  231. _DEFUN(exp, (x),
  232.     double x)
  233. {
  234.   double value;
  235.  
  236.   __asm ("fetox%.x %1,%0"
  237.      : "=f" (value)
  238.      : "f" (x));
  239.   return value;
  240. }
  241.  
  242. __inline static _CONST double 
  243. _DEFUN(expm1, (x),
  244.     double x)
  245. {
  246.   double value;
  247.  
  248.   __asm ("fetoxm1%.x %1,%0"
  249.      : "=f" (value)
  250.      : "f" (x));
  251.   return value;
  252. }
  253.  
  254. __inline static _CONST double 
  255. _DEFUN(log, (x),
  256.     double x)
  257. {
  258.   double value;
  259.  
  260.   __asm ("flogn%.x %1,%0"
  261.      : "=f" (value)
  262.      : "f" (x));
  263.   return value;
  264. }
  265.  
  266. __inline static _CONST double 
  267. _DEFUN(log1p, (x),
  268.     double x)
  269. {
  270.   double value;
  271.  
  272.   __asm ("flognp1%.x %1,%0"
  273.      : "=f" (value)
  274.      : "f" (x));
  275.   return value;
  276. }
  277.  
  278. __inline static _CONST double 
  279. _DEFUN(log10, (x),
  280.     double x)
  281. {
  282.   double value;
  283.  
  284.   __asm ("flog10%.x %1,%0"
  285.      : "=f" (value)
  286.      : "f" (x));
  287.   return value;
  288. }
  289.  
  290. __inline static _CONST double 
  291. _DEFUN(sqrt, (x),
  292.     double x)
  293. {
  294.   double value;
  295.  
  296.   __asm ("fsqrt%.x %1,%0"
  297.      : "=f" (value)
  298.      : "f" (x));
  299.   return value;
  300. }
  301.  
  302. __inline static _CONST double
  303. hypot (_CONST double x, _CONST double y)
  304. {
  305.   return sqrt (x*x + y*y);
  306. }
  307.  
  308. __inline static _CONST double 
  309. _DEFUN(pow, (x, y),
  310.     _CONST double x _AND
  311.     _CONST double y)
  312. {
  313.   if (x > 0)
  314.     return exp (y * log (x));
  315.   else if (x == 0)
  316.     {
  317.       if (y > 0)
  318.     return 0.0;
  319.       else
  320.     {
  321.       double value;
  322. #ifdef _KERNEL
  323.       usetup;
  324. #endif
  325.  
  326.       errno = EDOM;
  327.       __asm ("fmove%.d %#0rnan,%0"        /* quiet NaN */
  328.          : "=f" (value)
  329.          : /* no inputs */);
  330.       return value;
  331.     }
  332.     }
  333.   else    /* x < 0 */
  334.     {
  335.       double temp;
  336.  
  337.       __asm ("fintrz%.x %1,%0"
  338.          : "=f" (temp)            /* integer-valued float */
  339.          : "f" (y));
  340.       if (y == temp)
  341.         {
  342.       int i = (int) y;
  343.       
  344.       if ((i & 1) == 0)            /* even */
  345.         return exp (y * log (-x));
  346.       else
  347.         return - exp (y * log (-x));
  348.         }
  349.       else
  350.         {
  351.       double value;
  352. #ifdef _KERNEL
  353.       usetup;
  354. #endif
  355.  
  356.       errno = EDOM;
  357.       __asm ("fmove%.d %#0rnan,%0"        /* quiet NaN */
  358.          : "=f" (value)
  359.          : /* no inputs */);
  360.       return value;
  361.         }
  362.     }
  363. }
  364.  
  365. __inline static _CONST double 
  366. _DEFUN(fabs, (x),
  367.     double x)
  368. {
  369.   double value;
  370.  
  371.   __asm ("fabs%.x %1,%0"
  372.      : "=f" (value)
  373.      : "f" (x));
  374.   return value;
  375. }
  376.  
  377. __inline static _CONST double 
  378. _DEFUN(ceil, (x),
  379.     double x)
  380. {
  381.   int rounding_mode, round_up;
  382.   double value;
  383.  
  384.   __asm __volatile ("fmove%.l fpcr,%0"
  385.           : "=dm" (rounding_mode)
  386.           : /* no inputs */ );
  387.   round_up = rounding_mode | 0x30;
  388.   __asm __volatile ("fmove%.l %0,fpcr"
  389.           : /* no outputs */
  390.           : "dmi" (round_up));
  391.   __asm __volatile ("fint%.x %1,%0"
  392.           : "=f" (value)
  393.           : "f" (x));
  394.   __asm __volatile ("fmove%.l %0,fpcr"
  395.           : /* no outputs */
  396.           : "dmi" (rounding_mode));
  397.   return value;
  398. }
  399.  
  400. __inline static _CONST double 
  401. _DEFUN(floor, (x),
  402.     double x)
  403. {
  404.   int rounding_mode, round_down;
  405.   double value;
  406.  
  407.   __asm __volatile ("fmove%.l fpcr,%0"
  408.           : "=dm" (rounding_mode)
  409.           : /* no inputs */ );
  410.   round_down = (rounding_mode & ~0x10)
  411.         | 0x20;
  412.   __asm __volatile ("fmove%.l %0,fpcr"
  413.           : /* no outputs */
  414.           : "dmi" (round_down));
  415.   __asm __volatile ("fint%.x %1,%0"
  416.           : "=f" (value)
  417.           : "f" (x));
  418.   __asm __volatile ("fmove%.l %0,fpcr"
  419.           : /* no outputs */
  420.           : "dmi" (rounding_mode));
  421.   return value;
  422. }
  423.  
  424. __inline static _CONST double 
  425. _DEFUN(rint, (x),
  426.     double x)
  427. {
  428.   int rounding_mode, round_nearest;
  429.   double value;
  430.  
  431.   __asm __volatile ("fmove%.l fpcr,%0"
  432.           : "=dm" (rounding_mode)
  433.           : /* no inputs */ );
  434.   round_nearest = rounding_mode & ~0x30;
  435.   __asm __volatile ("fmove%.l %0,fpcr"
  436.           : /* no outputs */
  437.           : "dmi" (round_nearest));
  438.   __asm __volatile ("fint%.x %1,%0"
  439.           : "=f" (value)
  440.           : "f" (x));
  441.   __asm __volatile ("fmove%.l %0,fpcr"
  442.           : /* no outputs */
  443.           : "dmi" (rounding_mode));
  444.   return value;
  445. }
  446.  
  447. __inline static _CONST double 
  448. _DEFUN(fmod, (x, y),
  449.     double x _AND
  450.     double y)
  451. {
  452.   double value;
  453.  
  454.   __asm ("fmod%.x %2,%0"
  455.      : "=f" (value)
  456.      : "0" (x),
  457.        "f" (y));
  458.   return value;
  459. }
  460.  
  461. __inline static _CONST double 
  462. _DEFUN(drem, (x, y),
  463.     double x _AND
  464.     double y)
  465. {
  466.   double value;
  467.  
  468.   __asm ("frem%.x %2,%0"
  469.      : "=f" (value)
  470.      : "0" (x),
  471.        "f" (y));
  472.   return value;
  473. }
  474.  
  475. __inline static _CONST double 
  476. _DEFUN(scalb, (x, n),
  477.     double x _AND
  478.     int n)
  479. {
  480.   double value;
  481.  
  482.   __asm ("fscale%.l %2,%0"
  483.      : "=f" (value)
  484.      : "0" (x),
  485.        "dmi" (n));
  486.   return value;
  487. }
  488.  
  489. __inline static double 
  490. _DEFUN(logb, (x),
  491.     double x)
  492. {
  493.   double exponent;
  494.  
  495.   __asm ("fgetexp%.x %1,%0"
  496.      : "=f" (exponent)
  497.      : "f" (x));
  498.   return exponent;
  499. }
  500.  
  501. __inline static _CONST double 
  502. _DEFUN(ldexp, (x, n),
  503.     double x _AND
  504.     int n)
  505. {
  506.   double value;
  507.  
  508.   __asm ("fscale%.l %2,%0"
  509.      : "=f" (value)
  510.      : "0" (x),
  511.        "dmi" (n));
  512.   return value;
  513. }
  514.  
  515. __inline static double 
  516. _DEFUN(frexp, (x, exp),
  517.     double x _AND
  518.     int *exp)
  519. {
  520.   double float_exponent;
  521.   int int_exponent;
  522.   double mantissa;
  523.  
  524.   __asm ("fgetexp%.x %1,%0"
  525.      : "=f" (float_exponent)     /* integer-valued float */
  526.      : "f" (x));
  527.   int_exponent = (int) float_exponent;
  528.   __asm ("fgetman%.x %1,%0"
  529.      : "=f" (mantissa)        /* 1.0 <= mantissa < 2.0 */
  530.      : "f" (x));
  531.   if (mantissa != 0)
  532.     {
  533.       __asm ("fscale%.b %#-1,%0"
  534.          : "=f" (mantissa)        /* mantissa /= 2.0 */
  535.          : "0" (mantissa));
  536.       int_exponent += 1;
  537.     }
  538.   *exp = int_exponent;
  539.   return mantissa;
  540. }
  541.  
  542. __inline static double 
  543. _DEFUN(modf, (x, ip),
  544.     double x _AND
  545.     double *ip)
  546. {
  547.   double temp;
  548.  
  549.   __asm ("fintrz%.x %1,%0"
  550.      : "=f" (temp)            /* integer-valued float */
  551.      : "f" (x));
  552.   *ip = temp;
  553.   return x - temp;
  554. }
  555.  
  556. #undef _DEFUN
  557. #undef _AND
  558. #undef _CONST
  559.